#ifndef BITMAP_INDEX_H
#define BITMAP_INDEX_H

#include "index_manager.h"
#include "../memory/memory_manager.h"
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>

// Bitmap index configuration
#define BITMAP_BLOCK_SIZE 64         // 64-bit blocks for efficiency
#define BITMAP_MAX_CARDINALITY 1024  // Maximum distinct values
#define BITMAP_RESIZE_THRESHOLD 0.8  // Resize when 80% full

// Bitmap block type
typedef uint64_t bitmap_block_t;

// Bitmap structure for a single distinct value
typedef struct bitmap {
    bitmap_block_t* blocks;     // Array of bitmap blocks
    uint32_t block_count;       // Number of blocks
    uint32_t capacity_bits;     // Total capacity in bits
    uint32_t set_bits;          // Number of set bits (for statistics)
    
    // Memory management
    memory_manager_t* memory_mgr;
} bitmap_t;

// Value entry in bitmap index
typedef struct bitmap_value_entry {
    void* value;                // The distinct value
    size_t value_size;          // Size of the value
    bitmap_t* bitmap;           // Bitmap for this value
    uint32_t value_id;          // Unique ID for this value
    uint64_t count;             // Number of records with this value
    
    // Hash chain for value lookup
    struct bitmap_value_entry* hash_next;
} bitmap_value_entry_t;

// Forward declarations
typedef struct bitmap_index bitmap_index_t;
typedef struct bitmap_iterator bitmap_iterator_t;

// Bitmap index structure
struct bitmap_index {
    // Value storage and lookup
    bitmap_value_entry_t** value_hash_table;  // Hash table for value lookup
    uint32_t hash_table_size;                 // Size of hash table
    uint32_t distinct_values;                 // Number of distinct values
    uint32_t max_cardinality;                 // Maximum allowed distinct values
    
    // Bitmap storage
    uint32_t total_records;                   // Total number of records
    uint32_t capacity_records;                // Current capacity
    
    // NULL value handling
    bitmap_t* null_bitmap;                    // Bitmap for NULL values
    uint64_t null_count;                      // Number of NULL values
    
    // Memory management
    memory_manager_t* memory_mgr;
    
    // Thread safety
    pthread_rwlock_t rwlock;
    
    // Statistics
    uint64_t searches;
    uint64_t inserts;
    uint64_t deletes;
    uint64_t updates;
    uint64_t range_scans;
    
    // Configuration
    bool allow_duplicates;
    bool auto_resize;
};

// Bitmap iterator for scanning
struct bitmap_iterator {
    bitmap_index_t* index;         // Parent index
    bitmap_t* current_bitmap;      // Current bitmap being scanned
    uint32_t current_record;       // Current record position
    uint32_t end_record;           // End record position
    bool forward;                  // Scan direction
    bool is_valid;                 // Iterator validity
    
    // Value filtering
    void* filter_value;            // Filter by specific value (NULL = all)
    size_t filter_value_size;      // Size of filter value
    bitmap_value_entry_t* filter_entry; // Entry for filtered value
    
    // Multi-value iteration state
    bitmap_value_entry_t* current_value_entry; // Current value entry
    uint32_t value_index;          // Index in value table
};

// Bitmap index interface functions
index_interface_t* bitmap_index_interface_create(void);

// Bitmap index implementation functions
bitmap_index_t* bitmap_index_create(memory_manager_t* memory_mgr, uint32_t initial_capacity);
void bitmap_index_destroy(bitmap_index_t* bitmap_idx);

// Core operations
index_result_t bitmap_index_insert(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  const void* value, size_t value_size);
index_result_t bitmap_index_delete(bitmap_index_t* bitmap_idx, const void* key, size_t key_size);
index_result_t bitmap_index_search(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  index_search_result_t* result);
index_result_t bitmap_index_update(bitmap_index_t* bitmap_idx, const void* key, size_t key_size,
                                  const void* value, size_t value_size);

// Range operations
bitmap_iterator_t* bitmap_index_range_scan(bitmap_index_t* bitmap_idx,
                                          const void* start_key, size_t start_key_size,
                                          const void* end_key, size_t end_key_size,
                                          bool forward);

// Iterator operations
bool bitmap_iterator_valid(bitmap_iterator_t* iter);
index_result_t bitmap_iterator_next(bitmap_iterator_t* iter);
index_result_t bitmap_iterator_current(bitmap_iterator_t* iter,
                                      void** key, size_t* key_size,
                                      void** value, size_t* value_size);
void bitmap_iterator_destroy(bitmap_iterator_t* iter);

// Bulk operations
index_result_t bitmap_index_bulk_insert(bitmap_index_t* bitmap_idx,
                                       const void** keys, size_t* key_sizes,
                                       const void** values, size_t* value_sizes,
                                       size_t count);
size_t bitmap_index_range_delete(bitmap_index_t* bitmap_idx,
                                const void* start_key, size_t start_key_size,
                                const void* end_key, size_t end_key_size);

// Management operations
index_result_t bitmap_index_clear(bitmap_index_t* bitmap_idx);
index_result_t bitmap_index_rebuild(bitmap_index_t* bitmap_idx);
bool bitmap_index_validate(bitmap_index_t* bitmap_idx);
void bitmap_index_get_stats(bitmap_index_t* bitmap_idx, index_stats_t* stats);

// Bitmap operations
bitmap_t* bitmap_create(memory_manager_t* memory_mgr, uint32_t initial_capacity);
void bitmap_destroy(bitmap_t* bitmap);
index_result_t bitmap_set_bit(bitmap_t* bitmap, uint32_t bit_position);
index_result_t bitmap_clear_bit(bitmap_t* bitmap, uint32_t bit_position);
bool bitmap_get_bit(bitmap_t* bitmap, uint32_t bit_position);
index_result_t bitmap_resize(bitmap_t* bitmap, uint32_t new_capacity);

// Bitmap logical operations
bitmap_t* bitmap_and(bitmap_t* bitmap1, bitmap_t* bitmap2, memory_manager_t* memory_mgr);
bitmap_t* bitmap_or(bitmap_t* bitmap1, bitmap_t* bitmap2, memory_manager_t* memory_mgr);
bitmap_t* bitmap_xor(bitmap_t* bitmap1, bitmap_t* bitmap2, memory_manager_t* memory_mgr);
bitmap_t* bitmap_not(bitmap_t* bitmap, memory_manager_t* memory_mgr);

// Value management
bitmap_value_entry_t* bitmap_find_value_entry(bitmap_index_t* bitmap_idx, 
                                             const void* value, size_t value_size);
bitmap_value_entry_t* bitmap_create_value_entry(bitmap_index_t* bitmap_idx,
                                               const void* value, size_t value_size);
void bitmap_destroy_value_entry(bitmap_value_entry_t* entry, memory_manager_t* memory_mgr);
uint32_t bitmap_hash_value(const void* value, size_t value_size);

// Index management
index_result_t bitmap_index_resize(bitmap_index_t* bitmap_idx, uint32_t new_capacity);
index_result_t bitmap_index_compact(bitmap_index_t* bitmap_idx);
double bitmap_index_get_selectivity(bitmap_index_t* bitmap_idx, const void* value, size_t value_size);

// Utility functions
uint32_t bitmap_count_set_bits(bitmap_t* bitmap);
uint32_t bitmap_find_first_set_bit(bitmap_t* bitmap, uint32_t start_position);
uint32_t bitmap_find_next_set_bit(bitmap_t* bitmap, uint32_t current_position);
void bitmap_print(bitmap_t* bitmap);
void bitmap_index_print_stats(bitmap_index_t* bitmap_idx);

// Optimization functions
index_result_t bitmap_optimize_storage(bitmap_index_t* bitmap_idx);
bool bitmap_should_use_bitmap_index(uint32_t total_records, uint32_t distinct_values);

#endif // BITMAP_INDEX_H